package com.phonetools.commonutils.number

import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.charset.Charset

/**
 * 把ByteArray以指定的[charset]和[len]转为字符串
 * @param  charset
 * @param  len
 * @return 返回转换后的字符串
 */
fun ByteArray.toString(charset: Charset, len: Int): String {
    val fixLen =
        when {
            len > this.size -> this.size
            len < 0 -> 0
            else -> len
        }
    val lenArray = ByteArray(fixLen)
    forEachIndexed { index, byte ->
        if (index < fixLen)
            lenArray[index] = byte
    }

    return lenArray.toString(charset)
}

/**
 * 把ByteArray以指定的[charset]转为字符串,并忽略=[ignore]的内容
 * @param  charset
 * @param  ignore 需要忽略的内容
 * @return 返回转换后的字符串
 */
fun ByteArray.toStringIgnore(charset: Charset, ignore: String): String {
    return this.toString(charset).replace(ignore, "")
}

/**
 * 把ByteArray转为ASCII字符串
 * 例：0x 31 32 33 -> "123"
 * @return 返回转换后的字符串
 */
fun ByteArray.toAscii(): String {
    val result: StringBuilder = StringBuilder()
    this.forEach {
        result.append(it.toInt().toChar())
    }
    return result.toString()
}

/**
 * 把ByteArray以指定长度[len]转为ASCII字符串
 * @param len 字符串长度
 * 例：0x 31 32 33 ,len=2 -> "12"
 * @return 返回转换后的字符串
 */
fun ByteArray.toAscii(len: Int): String {
    val fixLen =
        when {
            len > this.size -> this.size
            len < 0 -> 0
            else -> len
        }
    val result: StringBuilder = StringBuilder()
    this.forEachIndexed { index, byte ->
        if (index < fixLen) {
            result.append(byte.toInt().toChar())
        }
    }
    return result.toString()
}

/**
 * 把ByteArray转为ASCII字符串，并忽略=[ignore]的内容
 * @param ignore 要忽略的内容
 * 例：0x 31 32 33 FF-> "123"
 * @return 返回转换后的字符串
 */
fun ByteArray.toAsciiIgnore(ignore: Byte = 0xff.toByte()): String {
    val result: StringBuilder = StringBuilder()
    this.forEach {
        if (it != ignore) {
            result.append(it.toInt().toChar())
        }
    }
    return result.toString()
}

/**
 * 计算ByteArray的校验和，结果为1位Byte
 * 例：0x 01 01 00 04 1E 0A 01 04 03 00 01 0A 01 3C 01 00 -> 0x 7F
 * @return 返回1位Byte
 */
fun ByteArray.sumCheck(): Byte {
    var sum: Byte = 0
    this.forEach {
        sum = (sum + it).toByte()
    }
    return sum
}

/**
 * 把字符串转为ByteArray
 * 例："123" -> 0x 31 32 33
 * @return 返回ByteArray
 */
fun String.asciiToByteArray(): ByteArray {
    return this.toByteArray(Charsets.US_ASCII)
}

/**
 * 把字符串转为ByteArray，可以指定编码，长度，长度不足时默认的占位字节内容
 * @param charset 编码方式
 * @param fixLen 修正长度
 * @param default 默认字节占位内容
 * @return 返回ByteArray
 */
fun String.toByteArray(
    charset: Charset = Charsets.UTF_8,
    fixLen: Int,
    default: Byte = 0x0
): ByteArray {
    val byteArray = this.toByteArray(charset)
    when {
        fixLen <= 0 -> {
            return "".toByteArray(charset)
        }
        byteArray.size > fixLen -> {
            return byteArray.sliceArray(0 until fixLen)
        }
        byteArray.size == fixLen -> {
            return byteArray
        }
        byteArray.size < fixLen -> {
            val lackOfCount = fixLen - byteArray.size
            val lackOfArray = ByteArray(lackOfCount) {
                default
            }
            return byteArray + lackOfArray
        }
        else -> {
            return byteArray
        }
    }
}

/**
 * 把ByteArray以 order序 转换为Short
 * @param order 字节序
 * @return 返回转换为Short
 */
fun ByteArray.toShort(order: ByteOrder): Short {
    /*if (this.size != 2) throw NumberFormatException("ByteArray Size != 2")
    val byteBuffer = ByteBuffer.wrap(this)
    return byteBuffer.order(order).short*/
    return ByteArrayUtils.byteArrayToShort(this, order)
}

/**
 * 把ByteArray以 order序 转换为Int
 * @param order 字节序
 * @return 返回Int
 */
fun ByteArray.toInt(order: ByteOrder): Int {
    /*if (this.size != 4) throw NumberFormatException("ByteArray Size != 4")
    val byteBuffer = ByteBuffer.wrap(this)
    return byteBuffer.order(order).int*/
    return ByteArrayUtils.byteArrayToInt(this, order)
}

/**
 * 把ByteArray以 order序 转换为Long
 * @param order 字节序
 * @return 返回Long
 */
fun ByteArray.toLong(order: ByteOrder): Long {
    if (this.size != 8) throw NumberFormatException("ByteArray Size != 8")
    val byteBuffer = ByteBuffer.wrap(this)
    return byteBuffer.order(order).long
}

/**
 * 把Short以 order序 转换为ByteArray
 * @param order 字节序
 * @return 返回ByteArray
 */
fun Short.toByteArray(order: ByteOrder): ByteArray {
    /*val byteBuffer = ByteBuffer.allocate(2).order(order)
    byteBuffer.asShortBuffer().put(this)
    return byteBuffer.array()*/
    return ByteArrayUtils.shortToByteArray(this, order)
}

/**
 * 把Int以 order序 转换为ByteArray
 * @param order 字节序
 * @return 返回ByteArray
 */
fun Int.toByteArray(order: ByteOrder): ByteArray {
    /*val byteBuffer = ByteBuffer.allocate(4).order(order)
    byteBuffer.asIntBuffer().put(this)
    return byteBuffer.array()*/
    return ByteArrayUtils.intToByteArray(this, order)
}

/**
 * 把Long以 order序 转换为ByteArray
 * @param order 字节序
 * @return 返回ByteArray
 */
fun Long.toByteArray(order: ByteOrder): ByteArray {
    val byteBuffer = ByteBuffer.allocate(8).order(order)
    byteBuffer.asLongBuffer().put(this)
    return byteBuffer.array()
}